package com.demo.petshop.service.impl;

import com.demo.petshop.entity.CartItems;
import com.demo.petshop.entity.Products;
import com.demo.petshop.mapper.CartItemsMapper;
import com.demo.petshop.mapper.ProductSpecsMapper;
import com.demo.petshop.mapper.ProductsMapper;
import com.demo.petshop.service.CartItemsService;
import com.demo.petshop.util.Result;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.sqlite.date.DateFormatUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;

import static com.demo.petshop.entity.table.CartItemsTableDef.CART_ITEMS;
import static com.demo.petshop.entity.table.ProductSpecsTableDef.PRODUCT_SPECS;
import static com.demo.petshop.entity.table.ProductsTableDef.PRODUCTS;
import static com.demo.petshop.entity.table.StoresTableDef.STORES;
import static com.mybatisflex.core.query.QueryMethods.sum;

/**
 * 服务层实现。
 *
 * @author lenovo
 * @since 2025-06-11
 */
@Service
public class CartItemsServiceImpl extends ServiceImpl<CartItemsMapper, CartItems> implements CartItemsService {

    @Autowired
    private ProductsMapper productsMapper;
    @Autowired
    private CartItemsMapper cartItemsMapper;
    @Autowired
    private ProductSpecsMapper productSpecsMapper;

    private int getUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        return loginUser.getUser().getUserId();
    }

    private boolean isAmple(int productId, int quantity) {
        Products products = productsMapper.selectOneByQuery(new QueryWrapper()
                .from(PRODUCTS)
                .where(PRODUCTS.PRODUCT_ID.eq(productId))
        );
        return (quantity <= products.getStock());
    }

    private int totalQuantity(int productId){
        int userId = getUserId();
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper
                .select(sum(CART_ITEMS.QUANTITY))
                .from(CART_ITEMS)
                .where(CART_ITEMS.USER_ID.eq(userId))
                .and(CART_ITEMS.PRODUCT_ID.eq(productId));
        Integer totalQuantity = (Integer) cartItemsMapper.selectObjectByQuery(queryWrapper);
        if (totalQuantity != null) totalQuantity += 0;
        else totalQuantity = 0;
        return totalQuantity;
    }

    private QueryWrapper getCartById(int cartItemId){
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper
                .from(CART_ITEMS)
                .where(CART_ITEMS.CART_ITEM_ID.eq(cartItemId));
        return queryWrapper;
    }


    @Override
    public Object getCart() {
        int userId = getUserId();
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper
                .select(PRODUCTS.ALL_COLUMNS, CART_ITEMS.QUANTITY, CART_ITEMS.SELECTED, STORES.NAME.as("storeName"),
                        CART_ITEMS.CART_ITEM_ID.as("cartItemId"), PRODUCT_SPECS.VALUE.as("specValue"),PRODUCT_SPECS.DELETED.as("specDelete"))
                .from(PRODUCTS)
                .join(CART_ITEMS).on(CART_ITEMS.PRODUCT_ID.eq(PRODUCTS.PRODUCT_ID))
                .join(PRODUCT_SPECS).on(PRODUCT_SPECS.SPEC_ID.eq(CART_ITEMS.SPEC_ID))
                .join(STORES).on(STORES.STORE_ID.eq(PRODUCTS.STORE_ID))
                .where(CART_ITEMS.USER_ID.eq(userId));
        List<Products> products = productsMapper.selectListByQuery(queryWrapper);
        for (Products outerProduct : products) {
            int quantity = 0;
            for (Products innerProduct : products) {
                if (Objects.equals(innerProduct.getProductId(), outerProduct.getProductId())) {
                    quantity += innerProduct.getQuantity();
                }
            }
            if (isAmple(outerProduct.getProductId(), quantity))
                outerProduct.setIsAmple(1);
            else
                outerProduct.setIsAmple(0);
        }
        return Result.success(products);
    }

    @Override
    public Object addToCart(int productId, int quantity, int specId) {
        int userId = getUserId();
        CartItems cartItems = cartItemsMapper.selectOneByQuery(
                new QueryWrapper()
                        .select()
                        .from(CART_ITEMS)
                        .where(CART_ITEMS.USER_ID.eq(userId)
                                .and(CART_ITEMS.PRODUCT_ID.eq(productId))
                                .and(CART_ITEMS.SPEC_ID.eq(specId))
                        )
        );

        int totalQuantity = totalQuantity(productId);

        Result result;
        if (cartItems != null) {

            if (isAmple(productId, totalQuantity + quantity)) {
                cartItems.setQuantity(cartItems.getQuantity() + quantity);
                cartItems.setSelected(1);
                result = Result.success(cartItemsMapper.update(cartItems));
            } else
                result = Result.success("库存不足");
        } else {
            if (isAmple(productId, totalQuantity + quantity)) {
                cartItems = new CartItems();
                cartItems.setUserId(userId);
                cartItems.setProductId(productId);
                cartItems.setQuantity(quantity);
                cartItems.setSelected(0);
                cartItems.setSpecId(specId);
                cartItems.setSelected(1);
                cartItems.setCreatedAt(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss.SSS"));
                result = Result.success(cartItemsMapper.insert(cartItems));
            } else
                result = Result.success("库存不足");
        }
        return result;
    }

    @Override
    public Object updateCartQuantity(int cartItemId,int quantity){
        CartItems cartItems = cartItemsMapper.selectOneByQuery(getCartById(cartItemId));
        int totalQuantity = totalQuantity(cartItems.getProductId());
        if(isAmple(cartItems.getProductId(),totalQuantity+quantity-cartItems.getQuantity())){
            cartItems.setQuantity(quantity);
            return Result.success(cartItemsMapper.update(cartItems));
        }
        else
            return Result.success("库存不足");
    }

    @Override
    public Object removeFromCart(int cartItemId) {
        return Result.success(cartItemsMapper.deleteByQuery(getCartById(cartItemId)));
    }

    @Override
    public Object updateCartSelection(int cartItemId, int selected) {
        CartItems cartItems = cartItemsMapper.selectOneByQuery(getCartById(cartItemId));
            cartItems.setSelected(selected);
        return Result.success(cartItemsMapper.update(cartItems));
    }

    @Override
    public Object addProductQuantity(int cartItemId) {
        CartItems cartItems = cartItemsMapper.selectOneByQuery(getCartById(cartItemId));
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper
                .select(sum(CART_ITEMS.QUANTITY))
                .from(CART_ITEMS)
                .where(CART_ITEMS.USER_ID.eq(cartItems.getUserId()))
                .and(CART_ITEMS.PRODUCT_ID.eq(cartItems.getProductId()));
        Integer totalQuantity = (Integer) cartItemsMapper.selectObjectByQuery(queryWrapper);

        if (isAmple(cartItems.getProductId(), totalQuantity + 1)) {
            cartItems.setQuantity(cartItems.getQuantity() + 1);
            return Result.success(cartItemsMapper.update(cartItems));
        } else
            return Result.success("库存不足");
    }

    @Override
    public Object disProductQuantity(int cartItemId) {
        CartItems cartItems = cartItemsMapper.selectOneByQuery(getCartById(cartItemId));
        if (cartItems.getQuantity() - 1 <= 0)
            removeFromCart(cartItemId);
        else
            cartItems.setQuantity(cartItems.getQuantity() - 1);
        return Result.success(cartItemsMapper.update(cartItems));
    }

}
